<?php
/**
* Desc
*
* @link
* @package pathnodes
* @subpackage zip
* @author J.Ducastel <jeremie@ducastel.name>
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

/**
 * checking for extension
* /
if (!function_exists('zip_open')) {
	trigger_error("missing zip extension ");
}/**/

/**
* registers as pathnode subclass
*/
pathnode::heritage('zipArchiveNode',10);

/**
*
* @uses
*/
class zipArchiveNode extends fileNode {
/*--------------------------------------------------------------------
CONSTRUCTOR
--------------------------------------------------------------------*/
	/**
	* constructor alias
	* @access public
	* /
	function () {
		$this->__construct();
	}/**/
	
	/**
	* "real" constructor
	* @access public
	* /
	function __construct() {
		
	}/**/
/*--------------------------------------------------------------------
PUBLIC STATIC METHODS
--------------------------------------------------------------------*/
	/**
	* 
	* @static
	* @param
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* @return bool
	*/
	function selfDetector($path) {
		return ereg('\.zip$',$path);
	}/**/
/*--------------------------------------------------------------------
PUBLIC INSTANCE METHODS
--------------------------------------------------------------------*/
	/**
	* get archive files as zipArchiveNode instances.
	* for some unknown reason, can't read opendocument archives...
	* @uses zip_open
	*
	* @param
	* @access public
	* @return array
	* /
	function & getChildren() {
		// building children array if not done yet
		if (!$this->children) {
			// reading archive
			$zip=zip_open($this->path);
			if ($zip) {
				while ($zip_entry = zip_read($zip)) {
        echo "Nom :               " . zip_entry_name($zip_entry) . "\n";
        echo "Taille du fichier :    " . zip_entry_filesize($zip_entry) . "\n";
        echo "Taille compressée :    " . zip_entry_compressedsize($zip_entry) . "\n";
        echo "Méthode de compression : " . zip_entry_compressionmethod($zip_entry) . "\n";

        if (zip_entry_open($zip, $zip_entry, "r")) {
            echo "Contenu du fichier :\n";
            $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
            echo "$buf\n";

            zip_entry_close($zip_entry);
        }
        echo "\n";

				}
				// closing archive
				zip_close($zip);
			}
		}
		return $this->children;
	}/**/
	
	/**
	* return archive files as zipChildNode instances
	* @access public
	* @return array
	*/
	function & getChildren() {
		if (!$this->children) {
			$this->_readChildrenFromFile();
		}
		return $this->children;
	}/**/

	/**
	* gets an item from the archive
	* @param
	* @access public
	* @return zipChildNode
	*/
	function & getChild($name) {
		$this->getchildren();
		if (isset($this->children[$name])) {
			return $this->children[$name];
		}
		$f=false; return $f;
	}/**/

	/**
	* extracts a child by index
	* @param int $index
	* @access public
	* @return string file's content
	*/
	function extractByIndex($index) {
		// $this->getChildren();
		$Z=&$this->_pclZip(); // echo $index;
		$result=$Z->extractByIndex($index,PCLZIP_OPT_EXTRACT_AS_STRING);
		//echo '<pre>'; print_r($result);
		return $result[0]['content'];
	}/**/

	/**
	* sends content for download.
	* uses Zip class from webappkit/pathnodes/zip/ziplib
	* @access public
	* @return bool
	* @uses zip
	*/
	function printContent() {
		// getting lib
		webappkit::loadkit('webappkit/pathnodes/zip/zipfile');
		// building zipfile object
		$zip=new zipfile();
		// looping through children
		$this->getChildren();
		foreach (array_keys($this->children) as $key) {
			// adding
			$zip->addFile(
				$this->children[$key]->content()
				, $this->children[$key]->fileName()
				,$this->children[$key]->mTime()
			);
		}
		echo $zip->file();
		return true;
	}/**/

	/**
	* force file download
	* @param
	* @access public
	* @return
	*/
	function download($filename=null) {
		if (!$filename)
			$filename=$this->getBaseName();
		// sending headers
		$this->_downloadHeaders($filename);
		// sending content
		return $this->printContent();
	}/**/

	/**
	* file size
	* @param
	* @access public
	* @return int
	* @todo : update when a child is updated
	*/
	function size() {
		return false;
	}/**/

	/**
	*
	* @param
	* @access public
	* @return
	* /
	function () {

	}/**/
/*--------------------------------------------------------------------
VARS / MEMBERS
--------------------------------------------------------------------*/
	/**
	* @var array zipChildNode instances
	*/
	var $children=array();
	
	/**
	 * @var PclZip slave instance
	 */
	var $_pclZip;
	
/*--------------------------------------------------------------------
PRIVATE / PROTECTED METHODS
--------------------------------------------------------------------*/

	/**
	* returns PclZip instance
	* @access protected
	* @return PclZip
	*/
	function & _pclZip() {
		// loading library
		webappkit::loadkit('webappkit/pathnodes/zip/pclzip');
		if (!$this->_pclZip) {
			$this->_pclZip=new PclZip($this->path);
		}
		return $this->_pclZip;
	}/**/
	
	/**
	 * reads children list from file
	 * @access protected
	 * @uses PclZip
	 * @return bool
	 */
	function _readChildrenFromFile() {
		$z=$this->_pclZip();
		$files=$z->listContent(); //echo '<pre>'; print_r($files);
		foreach ($files as $info) {
			$child=&new zipChildNode($this);
			$child->index($info['index']);
			$child->size($info['size']);
			$child->storedSize($info['compressed_size']);
			$child->filename($info['filename']);
			$child->storedFilename($info['stored_filename']);
			$child->isFolder($info['folder']);
			$child->mtime($info['mtime']);
			$child->comment($info['comment']);
			$key=$child->storedFileName();
			$this->children[$key]=&$child;
		}
		$prop=$z->properties();
		return $prop and $prop['status']=='ok';
	}/**/

}
?>